//
//  ZStreamStoragePrivate.h
//  Part of Z-Way.C library
//
//  Created by Pavel Kulaha on 19.06.2025.
//
//  Copyright (c) 2025 Z-Wave.Me
//  All rights reserved
//  info@z-wave.me
//
//  This source file is subject to the terms and conditions of the
//  Z-Wave.Me Software License Agreement which restricts the manner
//  in which it may be used.
//

#ifndef zstream_storage_private_h
#define zstream_storage_private_h

#include "ZStreamPrivate.h"
#include "ZArchivePrivate.h"
#include "ZDDXOperationsPrivate.h"

typedef struct _ZStreamStorageRwCtx_s
{
    union
    {
#if defined(__ZWAY_STORAGE_VIA_FILE__)
        struct
        {
            _ZStreamRWFileCtx_t ctx_rw_file;
            ZWSTR file_path;
            ZW_FILE_HANDLE fd;
        };
#endif
#if defined(__ZWAY_STORAGE_VIA_DH__)
        _ZStreamRWRamCtx_t ctx_rw_ram;
#endif
        ZWBYTE ctx_stream[1];
    };
    
    const _ZStreamRW_t *stream_rw;
    const _ZddxOperationsConfigCtx_t *ctx_zddx;
} _ZStreamStorageRwCtx_t;

typedef struct _ZStreamStorageUpdateRwCtx_s
{
    _ZStreamStorageRwCtx_t common;
    ZWWORD crc16;
} _ZStreamStorageUpdateRwCtx_t;

typedef struct _ZStreamStoragUpdateResult_s
{
    ZDataValue value;
    size_t size;
    ZWWORD crc16;
} _ZStreamStoragUpdateResult_t;

typedef struct _ZStreamStorageUpdateReaderCtx_s
{
    union
    {
#if defined(__ZWAY_STORAGE_VIA_DH__)
        _ZStreamCtxReaderRam_t ctx_reader_ram;
#endif
#if defined(__ZWAY_STORAGE_VIA_FILE__)
        _ZStreamCtxReaderFile_t ctx_reader_file;
#endif
        ZWBYTE ctx_stream[1];
    };
    
    const _ZStreamReader_t *reader;
} _ZStreamStorageUpdateReaderCtx_t;

typedef struct _ZStreamStorageRestoreRwCtx_t
{
    _ZStreamStorageRwCtx_t common;
    _ZArchiveGzUnpackCtx_t ctx_gz_unpack;
} _ZStreamStorageRestoreRwCtx_t;

typedef struct _ZStreamStoragRestoreResult_s
{
    union
    {
#if defined(__ZWAY_STORAGE_VIA_DH__)
        struct
        {
            _ZStreamCtxReaderRam_t ctx_reader_ram;
            _ZByteData_t data;
        };
#endif
#if defined(__ZWAY_STORAGE_VIA_FILE__)
        struct
        {
            _ZStreamCtxReaderFile_t ctx_reader_file;
            ZWSTR file_path;
        };
#endif
        ZWBYTE ctx_stream[1];
    };
    
    const _ZStreamReader_t *reader;
} _ZStreamStoragRestoreResult_t;

ZWEXPORT_PRIVATE const _ZStreamRW_t *_zstream_storage_update_rw(void);
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_rw_init(_ZStreamStorageUpdateRwCtx_t *const ctx, const _ZddxOperationsConfigCtx_t *const ctx_zddx, const ZWBOOL force_ram);
ZWEXPORT_PRIVATE void _zstream_storage_update_rw_free(_ZStreamStorageUpdateRwCtx_t *const ctx);
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_rw_end(_ZStreamStorageUpdateRwCtx_t *const ctx, _ZStreamStoragUpdateResult_t *const result);
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_rw_result_set(_ZddxOperationsConfigCtx_t *const ctx_zddx, _ZStreamStoragUpdateResult_t *const result, const ZDataHolder parent, const ZWDWORD device_id);
#if defined(__ZWAY_STORAGE_VIA_DH__)
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_rw_result_init_dh_not_allocated(_ZStreamStoragUpdateResult_t *const result, const ZWBYTE *const data, const size_t length);
#endif
static inline void _zstream_storage_update_rw_result_free(_ZStreamStoragUpdateResult_t *const result)
{
    return _zdata_free_value(&result->value);
}
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_reader_init(_ZStreamStorageUpdateReaderCtx_t *const ctx, const ZWLog log, const ZDataHolder parent);
static inline const _ZStreamReader_t *_zstream_storage_update_reader(const _ZStreamStorageUpdateReaderCtx_t *const ctx)
{
    return ctx->reader;
}
static inline void *_zstream_storage_update_reader_ctx(_ZStreamStorageUpdateReaderCtx_t *const ctx)
{
    return &ctx->ctx_stream[0];
}
ZWEXPORT_PRIVATE void _zstream_storage_update_reader_free(const _ZStreamStorageUpdateReaderCtx_t *const ctx);

ZWEXPORT_PRIVATE ZWError _zstream_storage_restore_rw_init(_ZStreamStorageRestoreRwCtx_t *const ctx, const _ZddxOperationsConfigCtx_t *const ctx_zddx, const ZWBOOL force_ram);
ZWEXPORT_PRIVATE void _zstream_storage_restore_rw_free(_ZStreamStorageRestoreRwCtx_t *const ctx);
ZWEXPORT_PRIVATE ZWError _zstream_storage_restore_rw_end(_ZStreamStorageRestoreRwCtx_t *const ctx, _ZStreamStoragRestoreResult_t *const result);
static inline const _ZStreamRW_t *_zstream_storage_restore_rw(const _ZStreamStorageRestoreRwCtx_t *const UNUSED(ctx))
{
    return _zarchive_stream_gz_unpack();
}
static inline void *_zstream_storage_update_restore_rw_ctx(_ZStreamStorageRestoreRwCtx_t *const ctx)
{
    return &ctx->ctx_gz_unpack;
}
static inline const _ZStreamReader_t *_zstream_storage_restore_reader(const _ZStreamStoragRestoreResult_t *const result)
{
    return result->reader;
}
static inline void *_zstream_storage_restore_reader_ctx(_ZStreamStoragRestoreResult_t *const result)
{
    return &result->ctx_stream[0];
}
ZWEXPORT_PRIVATE void _zstream_storage_restore_reader_free(_ZStreamStoragRestoreResult_t *const result);

#if defined(__ZWAY_STORAGE_VIA_FILE__)
ZWEXPORT_PRIVATE ZWError _zstream_storage_update_cache_use_list(const ZDataHolder parent, const ZWCSTR last_transmitted, _ZddxOperationsConfigCacheUse_t **const p_cache_use);
#endif

#endif // zstream_storage_private_h